#ifndef ___CHECKERBOARD__
#define ___CHECKERBOARD__
#include <iostream>
#include <conio.h>
#include "Pawn.h"
#include "ListOfPoint.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

class CheckerBoard
{
	public :
		// Konstanta
		static const bool WHITE = true;		// boolean penanda giliran putih
		static const bool BLACK = false;	// boolean penanda giliran hitam
		
		static const int END = 0;		
		static const int LT = 1;		
		static const int RT = 2;	
		static const int LB = 3;	
		static const int RB = 4;
		static const int START = 5;		

		static const int UNINITIALIZED = 0;		
		static const int GREEDYPAWNKING = 1;		
		static const int GREEDYKINGMOVE = 2;	
		static const int GREEDYROBERT = 3;	
		
		static const bool PLAYER = true;	
		static const int AI = false;	
		
		// General Purpose Attribute
		int numberOfPawn1;        // Sisa pawn white
		int numberOfPawn2;        // Sisa pawn black
		
		int type1;
		int type2;
		bool player1;
		bool player2;
		
		int size;				  // Ukuran Board
		
		int jumpAIx;
		int jumpAIy;
		int selectedPawnX;		  // Posisi X dari pawn yang ditunjuk
		int selectedPawnY;		  // Posisi Y dari pawn yang ditunjuk

		Pawn*** Board;        // Matriks checker board
		
		bool turn;				  // Giliran jalan 
		
		// AI Attribute
		ListOfPoint LoEat;		// List berisi posisi pawn yang bisa makan musuh, digunakan juga untuk memaksa player untuk makan
		ListOfPoint LoJump;		// List berisi posisi pawn, dan posisi selanjutnya setelah pawn makan
		ListOfPoint LoDanger;	// List berisi posisi pawn yang bisa dimakan musuh
		
		//Constructor dkk
		CheckerBoard();
		CheckerBoard(int sizes);
		CheckerBoard(const CheckerBoard&);
		~CheckerBoard();

		//Predikat
		bool isEatAllowed(int x, int y);                          // Di titik tersebut pawn bisa makan 
		bool isDanger(int x, int y);							  // Di titik tersebut pawn bisa dimakan
		bool isMoveAllowed(int x1, int y1, int x2, int y2);       // Dari titik asal bisa move ke titik tujuan
		bool isMoveable(int x, int y);     						  // Di titik (x,y) bisa move
		bool isExistPawn(int x, int y);                           // Di titik tersebut terdapat pawn
		bool isExistWhitePawn(int x, int y);					  // Di titik tersebut terdapat pawn putih
		bool isExistBlackPawn(int x, int y);					  // Di titik tersebut terdapat pawn hitam
		bool isExistWhiteKingPawn(int x, int y);				  // Di titik tersebut terdapat pawn rajs putih
		bool isExistBlackKingPawn(int x, int y);				  // Di titik tersebut terdapat pawn raja hitam
		bool isJump(int x1, int y1, int x2, int y2, bool check);  // Di titik awal bisa jump ke titik tujuan 
																  //	jika bool true -> cuma mengecek bisa jump atau ngga
																  //	jika bool false -> akan menghapus musuh yang dilewati
																  //					   dari titik awal ke titik akhir

		// Method lain
		void move(int x1, int y1, int x2, int y2);                			 	   // Move dari titik awal ke titik tujuan
		bool checkMove(bool turn);
		void checkEat(bool turn);		                         			 	   // Mengisi LoEat, dipanggil setiap awal turn		
		void checkSafe(bool turn);								 			 	   // Mengisi LoDanger, dipanggil setiap awal turn
		void checkJump(int x, int y);										 	   // Mengisi LoJump, dipanggil ketika mencari makan yang paling maksimal
		void printBoard();										 			 	   // Ntar juga ilang  
		void countNumberOfPawn();												
		
		// Fungsi untuk checkJump
		bool isJumpAvailable(int x1, int y1, int x2, int y2, bool side, bool isKing); 	 	// Mengembalikan bila pawn bohongan bisa jump dari (x1,y1) ke (x2,y2)
		bool isJumpAvailableLeftTop(int x1, int y1, bool side, bool isKing); 				// Mengembalikan bila pawn bohongan bisa jump dari (x1,y1) ke (x2,y2)
		bool isJumpAvailableRightTop(int x1, int y1, bool side, bool isKing); 				// Mengembalikan bila pawn bohongan bisa jump dari (x1,y1) ke (x2,y2)
		bool isJumpAvailableLeftBottom(int x1, int y1, bool side, bool isKing);  			// Mengembalikan bila pawn bohongan bisa jump dari (x1,y1) ke (x2,y2)
		bool isJumpAvailableRightBottom(int x1, int y1, bool side, bool isKing); 			// Mengembalikan bila pawn bohongan bisa jump dari (x1,y1) ke (x2,y2)
		int* searchMaximum(int x, int y, bool side, bool isKing, int* Move, int count);     // Mengembalikan nilai maksimum gerakkan makan yang mungkin
		int* maxList(int* list1, int* list2);							   					// Membandingkan panjang 2 buah list
		int listSize(int* list);
		
		// Method AI
		void moveAI(int type);									  // Gerakkin AInya lah
		void moveWhite1();										  // Gerakkin AI White1
		void moveBlack1();										  // Gerakkin AI Black1
		void moveWhite2();										  // Gerakkin AI White2
		void moveBlack2();										  // Gerakkin AI Black2
		bool isMoveSafetyBlack(int x, int y, int x0, int y0);     // Mengembalikan true jika gerakkan pawn putih ke titik (x,y) aman
		bool isMoveSafetyWhite(int x, int y, int x0, int y0);	  // Mengembalikan true jika gerakkan pawn hitam ke titik (x,y) aman
		bool isNoHopeBlack(int x, int y);						  // Mengembalikan nilai true jika pawn hitam tidak bisa kabur di titik (x,y)
		bool isNoHopeWhite(int x, int y);						  // Mengembalikan nilai true jika pawn putih tidak bisa kabur di titik (x,y)
		bool isExistNormalPawn();								  // Mengembalikan true jika ada Pawn biasa
		Point searchNearestEnemy(Point pawnPos, bool side); 	  // Mencari posisi pawn lawan terdekat
		Point minimumDistance(Point P1, Point P2, Point pawnPos); // Mengembalikan point yang terdekat dari pawnPos
		bool movePawnWhite(int state, int x, int y);									  // AI menggerakkan pawn putih
		bool movePawnBlack(int state, int x, int y);									  // AI menggerakkan pawn hitam
		bool movePawnKingWhite(int state, int x, int y);							      // AI menggerakkan pawn raja putih
		bool movePawnKingBlack(int state, int x, int y);							      // AI menggerakkan pawn raja hitam
		bool escapePawnBlack(int x, int y);									  // AI melarikan pawn hitam
		bool escapePawnWhite(int x, int y);									  // AI melarikan pawn putih
		bool escapePawnKingBlack(int x, int y);								  // AI melarikan pawn raja hitam
		bool escapePawnKingWhite(int x, int y);								  // AI melarikan pawn raja putih
		bool backupBlack(int x, int y);										  // AI melindungi pawn hitam
		bool backupWhite(int x, int y);										  // AI melindungi pawn putih
		void searchKing(ListOfPoint* LoKing);								  // Mengisi LoKing
		bool movePawnKingImmediate(int x, int y);
};

#endif
